#ifndef SYS_H
#define SYS_H

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

static const char netdev0_ip[] = "192.168.74.2";
static const char netdev0_gw[] = "192.168.74.1";
static const char friend0_ip[] = "192.168.74.3";
static const char netdev0_phy_ip[] = "172.20.208.1";    // 用于收发包的真实网卡ip地址，在qemu上不需要使用
static const char netdev0_mask[] = "255.255.240.0";
static const uint8_t netdev0_hwaddr[] = { 0x00, 0x15, 0x5D, 0x9E, 0xFC, 0xCB };

#define SYS_PLAT_WINDOWS

#if defined(SYS_PLAT_WINDOWS)
#include <windows.h>
#include <winbase.h>
#include <process.h>
#include <time.h>
#include <tchar.h>

typedef union {
    uint8_t pipe_msg[512];
    struct {
        uint8_t is_end; 
        uint32_t len;
        uint8_t msg[507];
    } pip_stru;
} __attribute__((packed)) PIPEMSG;

typedef DWORD net_time_t;      // 时间类型

#define SYS_THREAD_INVALID          (HANDLE)0
#define SYS_SEM_INVALID             (HANDLE)0
#define SYS_MUTEX_INVALID           (HANDLE)0
#define SYS_EVENT_INVALID           (HANDLE)0

typedef HANDLE sys_mutex_t;         // 互斥锁
typedef HANDLE sys_thread_t;        // 线程
typedef HANDLE sys_sem_t;           // 信号量
typedef HANDLE sys_event_t;

#define mnet_strlen         strlen
#define mnet_strcpy         strcpy
#define mnet_strncpy        strncpy
#define mnet_strcmp         strcmp
#define mnet_stricmp        _stricmp
#define mnet_memset         memset
#define mnet_memcpy         memcpy
#define mnet_memcmp         memcmp
#define mnet_sprintf        sprintf
#define mnet_vsprintf       vsprintf
#define mnet_printf         printf
#define mnet_malloc         malloc
#define mnet_free           free
#endif

#endif

sys_sem_t sys_sem_create(int init_count);
void sys_sem_free(sys_sem_t sem);
int sys_sem_wait(sys_sem_t sem, uint32_t ms);
void sys_sem_notify(sys_sem_t sem);

// 互斥信号量：由具体平台实现
sys_mutex_t sys_mutex_create(void);
void sys_mutex_free(sys_mutex_t mutex);
void sys_mutex_lock(sys_mutex_t mutex);
void sys_mutex_unlock(sys_mutex_t mutex);
int sys_mutex_is_valid(sys_mutex_t mutex);

sys_event_t sys_event_create(void *event_name);
int sys_event_wait(sys_event_t event_t, uint32_t ms);
void sys_event_notify(sys_event_t event_t);

// 线程相关：由具体平台实现
typedef void (*sys_thread_func_t)(void * arg);
sys_thread_t sys_thread_create(sys_thread_func_t entry, void* arg);
int sys_pipe_create(void *pipe_name, HANDLE *handle);
int sys_wait_pipe_create(void *pipe_name);
int sys_wait_client_connect(HANDLE pipe_name);
HANDLE sys_open_pipe(void *pipe_name);
void sys_pipe_read(HANDLE pipe_name, void *buffer, unsigned int size, void *r_size);
void sys_pipe_write(HANDLE pipe_name, void *buffer, unsigned int size, void *w_size);
int sys_get_pipe_client_id(HANDLE pipe_name, void *id);
int sys_pipe_write2(HANDLE pipe, char *msg, int len);
int sys_pipe_read2(HANDLE pipe, PIPEMSG *msg);
void sys_thread_exit (int error);
void sys_sleep(int ms);
sys_thread_t sys_thread_self (void);
int sys_time_goes (net_time_t * pre);
void sys_time_curr (net_time_t * time);

void sys_plat_init(void);